6  Tumor: Sub-clustering on T/NK lineage

6.1 Set up Seurat workspace

# Load libraries
library(data.table)
library(devtools)
library(presto)
library(glmGamPoi)
library(sctransform)
library(Seurat) 
library(tidyverse)
library(miQC)
library(SeuratWrappers)
library(flexmix)
library(SingleCellExperiment)
library(SummarizedExperiment)
library(readxl)
library(fishpond)
library(Matrix)
library(speckle)
library(scater)
library(patchwork)
library(vctrs)
library(alevinQC)
library(harmony)
library(scDblFinder)
library(cellXY)

# Set global options for Seurat v5 objects
options(Seurat.object.assay.version = 'v5')

6.2 Load previously saved clustered object

merged.18279.tumor.singlets <- readRDS("Tumor_scRNA_Part3.rds")

6.3 Set idents to preferred initial clustering resolution

Idents(merged.18279.tumor.singlets) <- merged.18279.tumor.singlets$RNA_snn_res.1
merged.18279.tumor.singlets$seurat_clusters <- merged.18279.tumor.singlets$RNA_snn_res.1
DimPlot(merged.18279.tumor.singlets, reduction="umap.harmony", label=T)

6.4 Run sub-clustering on T/NK lineage

T/NK cells are in clusters 1,2,3,9,12,16,18,22,26

6.4.1 Cluster 1

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets, 
                                        cluster = "1",
                                        resolution = 0.2,
                                        graph.name = "RNA_snn",  
                                        algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 2832
Number of edges: 96284

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8058
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,  
        reduction = "umap.harmony",  
        group.by = "sub.cluster", 
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11   12   13   14   15   16   17   18   19    2   20   21 
3244 2596  236  671  645  601  469  449  370  364  336  273  265 1338  249  228 
  22   23   24   25   26   27   28   29    3    4    5    6    7    8    9 
 201  113   77   74   55   33   30   27 1214 1171 1151  955  934  849  758 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"   "10"  "7"   "5"   "14"  "6"   "27"  "20"  "15"  "19"  "11"  "4"  
[13] "26"  "1_1" "3"   "1_0" "9"   "2"   "18"  "16"  "22"  "12"  "24"  "0"  
[25] "13"  "28"  "21"  "17"  "29"  "25"  "23" 

6.4.2 Cluster 2

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets, 
                                        cluster = "2",
                                        resolution = 0.2,
                                        graph.name = "RNA_snn",  
                                        algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1338
Number of edges: 50191

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8124
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,  
        reduction = "umap.harmony",  
        group.by = "sub.cluster", 
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11   12   13   14   15   16   17   18   19  2_0  2_1   20 
3244 2596  236  671  645  601  469  449  370  364  336  273  265 1142  196  249 
  21   22   23   24   25   26   27   28   29    3    4    5    6    7    8    9 
 228  201  113   77   74   55   33   30   27 1214 1171 1151  955  934  849  758 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"   "10"  "7"   "5"   "14"  "6"   "27"  "20"  "15"  "19"  "11"  "4"  
[13] "26"  "1_1" "3"   "1_0" "9"   "2_0" "18"  "16"  "22"  "12"  "24"  "0"  
[25] "13"  "28"  "2_1" "21"  "17"  "29"  "25"  "23" 

6.4.3 Cluster 3

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets, 
                                        cluster = "3",
                                        resolution = 0.2,
                                        graph.name = "RNA_snn",  
                                        algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1214
Number of edges: 44968

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8135
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,  
        reduction = "umap.harmony",  
        group.by = "sub.cluster", 
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11   12   13   14   15   16   17   18   19  2_0  2_1   20 
3244 2596  236  671  645  601  469  449  370  364  336  273  265 1142  196  249 
  21   22   23   24   25   26   27   28   29  3_0  3_1    4    5    6    7    8 
 228  201  113   77   74   55   33   30   27 1129   85 1171 1151  955  934  849 
   9 
 758 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"   "10"  "7"   "5"   "14"  "6"   "27"  "20"  "15"  "19"  "11"  "4"  
[13] "26"  "1_1" "3_0" "1_0" "9"   "2_0" "18"  "16"  "22"  "12"  "24"  "0"  
[25] "13"  "28"  "2_1" "3_1" "21"  "17"  "29"  "25"  "23" 

6.4.4 Cluster 9

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets, 
                                        cluster = "9",
                                        resolution = 0.2,
                                        graph.name = "RNA_snn",  
                                        algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 758
Number of edges: 22201

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8565
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,  
        reduction = "umap.harmony",  
        group.by = "sub.cluster", 
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11   12   13   14   15   16   17   18   19  2_0  2_1   20 
3244 2596  236  671  645  601  469  449  370  364  336  273  265 1142  196  249 
  21   22   23   24   25   26   27   28   29  3_0  3_1    4    5    6    7    8 
 228  201  113   77   74   55   33   30   27 1129   85 1171 1151  955  934  849 
 9_0  9_1 
 455  303 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"   "10"  "7"   "5"   "14"  "6"   "27"  "20"  "15"  "19"  "11"  "4"  
[13] "26"  "1_1" "3_0" "1_0" "9_0" "2_0" "18"  "16"  "22"  "12"  "24"  "0"  
[25] "13"  "28"  "2_1" "3_1" "9_1" "21"  "17"  "29"  "25"  "23" 

6.4.5 Cluster 12

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets, 
                                        cluster = "12",
                                        resolution = 0.2,
                                        graph.name = "RNA_snn",  
                                        algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 601
Number of edges: 21396

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8378
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,  
        reduction = "umap.harmony",  
        group.by = "sub.cluster", 
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11 12_0 12_1   13   14   15   16   17   18   19  2_0  2_1 
3244 2596  236  671  645  486  115  469  449  370  364  336  273  265 1142  196 
  20   21   22   23   24   25   26   27   28   29  3_0  3_1    4    5    6    7 
 249  228  201  113   77   74   55   33   30   27 1129   85 1171 1151  955  934 
   8  9_0  9_1 
 849  455  303 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"    "10"   "7"    "5"    "14"   "6"    "27"   "20"   "15"   "19"  
[11] "11"   "4"    "26"   "1_1"  "3_0"  "1_0"  "9_0"  "2_0"  "18"   "16"  
[21] "22"   "12_0" "12_1" "24"   "0"    "13"   "28"   "2_1"  "3_1"  "9_1" 
[31] "21"   "17"   "29"   "25"   "23"  

6.4.6 Cluster 16

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets, 
                                        cluster = "16",
                                        resolution = 0.2,
                                        graph.name = "RNA_snn",  
                                        algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 364
Number of edges: 13446

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8000
Number of communities: 1
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,  
        reduction = "umap.harmony",  
        group.by = "sub.cluster", 
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11 12_0 12_1   13   14   15 16_0   17   18   19  2_0  2_1 
3244 2596  236  671  645  486  115  469  449  370  364  336  273  265 1142  196 
  20   21   22   23   24   25   26   27   28   29  3_0  3_1    4    5    6    7 
 249  228  201  113   77   74   55   33   30   27 1129   85 1171 1151  955  934 
   8  9_0  9_1 
 849  455  303 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"    "10"   "7"    "5"    "14"   "6"    "27"   "20"   "15"   "19"  
[11] "11"   "4"    "26"   "1_1"  "3_0"  "1_0"  "9_0"  "2_0"  "18"   "16_0"
[21] "22"   "12_0" "12_1" "24"   "0"    "13"   "28"   "2_1"  "3_1"  "9_1" 
[31] "21"   "17"   "29"   "25"   "23"  

6.4.7 Cluster 18

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets,
                                                                                cluster = "18",
                                                                                resolution = 0.2,
                                                                                graph.name = "RNA_snn",
                                                                                algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 273
Number of edges: 9056

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8289
Number of communities: 2
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,
        reduction = "umap.harmony",
        group.by = "sub.cluster",
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11 12_0 12_1   13   14   15 16_0   17 18_0 18_1   19  2_0 
3244 2596  236  671  645  486  115  469  449  370  364  336  167  106  265 1142 
 2_1   20   21   22   23   24   25   26   27   28   29  3_0  3_1    4    5    6 
 196  249  228  201  113   77   74   55   33   30   27 1129   85 1171 1151  955 
   7    8  9_0  9_1 
 934  849  455  303 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"    "10"   "7"    "5"    "14"   "6"    "27"   "20"   "15"   "19"  
[11] "11"   "4"    "26"   "1_1"  "3_0"  "1_0"  "9_0"  "2_0"  "18_1" "16_0"
[21] "22"   "12_0" "18_0" "12_1" "24"   "0"    "13"   "28"   "2_1"  "3_1" 
[31] "9_1"  "21"   "17"   "29"   "25"   "23"  

6.4.8 Cluster 22

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets,
                                                                                cluster = "22",
                                                                                resolution = 0.2,
                                                                                graph.name = "RNA_snn",
                                                                                algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 201
Number of edges: 4598

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8141
Number of communities: 3
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,
        reduction = "umap.harmony",
        group.by = "sub.cluster",
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11 12_0 12_1   13   14   15 16_0   17 18_0 18_1   19  2_0 
3244 2596  236  671  645  486  115  469  449  370  364  336  167  106  265 1142 
 2_1   20   21 22_0 22_1 22_2   23   24   25   26   27   28   29  3_0  3_1    4 
 196  249  228  106   70   25  113   77   74   55   33   30   27 1129   85 1171 
   5    6    7    8  9_0  9_1 
1151  955  934  849  455  303 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"    "10"   "7"    "5"    "14"   "6"    "27"   "20"   "15"   "19"  
[11] "11"   "4"    "26"   "1_1"  "3_0"  "1_0"  "9_0"  "2_0"  "18_1" "16_0"
[21] "22_0" "12_0" "18_0" "12_1" "24"   "0"    "13"   "28"   "2_1"  "3_1" 
[31] "9_1"  "21"   "17"   "22_1" "29"   "22_2" "25"   "23"  

6.4.9 Cluster 26

merged.18279.tumor.singlets <- FindSubCluster(object = merged.18279.tumor.singlets,
                                                                                cluster = "26",
                                                                                resolution = 0.2,
                                                                                graph.name = "RNA_snn",
                                                                                algorithm = 2)
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 55
Number of edges: 1022

Running Louvain algorithm with multilevel refinement...
Maximum modularity in 10 random starts: 0.8000
Number of communities: 1
Elapsed time: 0 seconds
DimPlot(merged.18279.tumor.singlets,
        reduction = "umap.harmony",
        group.by = "sub.cluster",
        label = TRUE)

table(merged.18279.tumor.singlets$sub.cluster)

   0  1_0  1_1   10   11 12_0 12_1   13   14   15 16_0   17 18_0 18_1   19  2_0 
3244 2596  236  671  645  486  115  469  449  370  364  336  167  106  265 1142 
 2_1   20   21 22_0 22_1 22_2   23   24   25 26_0   27   28   29  3_0  3_1    4 
 196  249  228  106   70   25  113   77   74   55   33   30   27 1129   85 1171 
   5    6    7    8  9_0  9_1 
1151  955  934  849  455  303 
Idents(merged.18279.tumor.singlets) <- "sub.cluster"
levels(merged.18279.tumor.singlets)
 [1] "8"    "10"   "7"    "5"    "14"   "6"    "27"   "20"   "15"   "19"  
[11] "11"   "4"    "26_0" "1_1"  "3_0"  "1_0"  "9_0"  "2_0"  "18_1" "16_0"
[21] "22_0" "12_0" "18_0" "12_1" "24"   "0"    "13"   "28"   "2_1"  "3_1" 
[31] "9_1"  "21"   "17"   "22_1" "29"   "22_2" "25"   "23"  

6.5 Plot updated QC metrics per cluster/sub-cluster

VlnPlot(merged.18279.tumor.singlets, features = "nCount_RNA", group.by="sub.cluster", pt.size=0) + NoLegend()

VlnPlot(merged.18279.tumor.singlets, features = "nFeature_RNA", group.by="sub.cluster", pt.size=0) + NoLegend()

VlnPlot(merged.18279.tumor.singlets, features = "percent.mt", group.by="sub.cluster", pt.size=0) + NoLegend()

6.6 Identify updated cursory marker genes per cluster/sub-cluster

DefaultAssay(merged.18279.tumor.singlets) <- "RNA"

vargenes <- presto::wilcoxauc(merged.18279.tumor.singlets, 'sub.cluster', seurat_assay = 'RNA')
top_vargenes <- top_markers(vargenes, n = 100, auc_min = 0.5, pct_in_min = 50, pct_out_max = 50)
top_vargenes
# A tibble: 100 × 39
    rank `0`    `1_0` `1_1`   `10`  `11`  `12_0` `12_1` `13`  `14`  `15`  `16_0`
   <int> <chr>  <chr> <chr>   <chr> <chr> <chr>  <chr>  <chr> <chr> <chr> <chr> 
 1     1 MLANA  CCL5  GZMH    COL1… CRYAB GZMK   ITM2A  MZB1  PTTG1 IFI30 IL32  
 2     2 EDNRB  NKG7  NKG7    COL3… SERP… CST7   TOX    DERL3 TYMS  TYRO… LTB   
 3     3 TYR    CST7  GZMA    COL1… BANCR IL32   CXCL13 JCHA… NUCK… LYZ   FOXP3 
 4     4 CRTAC1 CD8A  CCL5    COL6… IFI27 CD3E   NR3C1  XBP1  CENPF ENSG… SPOCK2
 5     5 MITF   DUSP2 APOBEC… COL6… ANGP… GZMA   TIGIT  IGHG1 UBE2C CST3  CD3E  
 6     6 TYRP1  IL32  TGFB1   DCN   F2R   CD3D   LAT    ENSG… CKS1B PLAUR CTLA4 
 7     7 GPNMB  LAG3  CTSW    COL6… WARS1 RGS1   CD247  CD79A BIRC5 FCER… TIGIT 
 8     8 APOE   CD3E  PTPRC   C1S   ST3G… LAG3   CD2    IGHGP HMGN2 SPI1  CORO1A
 9     9 GMPR   CD8B  AOAH    C1R   HMCN1 DUSP2  CD3E   IGHG2 H2AZ2 AIF1  PTPRC 
10    10 GPM6B  CD7   TUBA4A  VCAN  RHOB  CD2    NMB    FKBP… MIA   TYMP  CD3D  
# ℹ 90 more rows
# ℹ 27 more variables: `17` <chr>, `18_0` <chr>, `18_1` <chr>, `19` <chr>,
#   `2_0` <chr>, `2_1` <chr>, `20` <chr>, `21` <chr>, `22_0` <chr>,
#   `22_1` <chr>, `22_2` <chr>, `23` <chr>, `24` <chr>, `25` <chr>,
#   `26_0` <chr>, `27` <chr>, `28` <chr>, `29` <chr>, `3_0` <chr>, `3_1` <chr>,
#   `4` <chr>, `5` <chr>, `6` <chr>, `7` <chr>, `8` <chr>, `9_0` <chr>,
#   `9_1` <chr>
write_tsv(top_vargenes,"Tumor_scRNA_prestoMarkers.tsv")

6.7 Plot top markers identified and canonical genes as a dotplot

tumor <- c("DCT","MLANA","MITF","PMEL","S100A1","TYR","APOC1")
endothelial <- c("PECAM1","VWF")
fibroblast <- c("COL3A1","COL1A1","COL1A2","LUM")
tcell <- c("FGFBP2","KLRD1","CD3E","CD3D","GZMB","XCL2","GZMH","CST7","GZMK","GZMA","IFNG","GNLY","CCL4","NKG7","CCL5","CD8A","CD8B","CTLA4","TNFRSF4","BATF","ITM2A")
mono <- c("LYZ","CD74","CD68")
bcell <- c("MS4A1","CD79A")

top_vargenes <- top_markers(vargenes, n = 5, auc_min = 0.5, pct_in_min = 50, pct_out_max = 50)
top_markers <- top_vargenes %>%
    select(-rank) %>% 
    unclass() %>% 
    stack() %>%
    pull(values) %>%
    unique() %>%
    .[!is.na(.)]

dotplotmarkers <- unique(c(top_markers,tumor,endothelial,fibroblast,tcell,mono,bcell))

# Compute aggregated expression values of these genes and cluster them to order the figure
rna <- AverageExpression(merged.18279.tumor.singlets,assay="RNA",slot="data")
As of Seurat v5, we recommend using AggregateExpression to perform pseudo-bulk analysis.
Names of identity class contain underscores ('_'), replacing with dashes ('-')
First group.by variable `ident` starts with a number, appending `g` to ensure valid variable names
This message is displayed once per session.
rna.sub <- rna$RNA[dotplotmarkers,]
cors.genes <- as.dist(1-cor(as.matrix(t(rna.sub)),method="pearson"))
hc.genes <- hclust(cors.genes)
dotplotmarkers.sorted <- rownames(rna.sub)[hc.genes$order]

# Also re-order the sub-clusters
cors.subs <- as.dist(1-cor(as.matrix(rna.sub),method="pearson"))
hc.subs <- hclust(cors.subs)
merged.18279.tumor.singlets@active.ident <- factor(merged.18279.tumor.singlets@active.ident, 
                            levels=str_replace_all(str_replace_all(colnames(rna.sub)[hc.subs$order],"g",""),"-","_"))

# Plot
DotPlot(merged.18279.tumor.singlets,
    features = dotplotmarkers.sorted,
    assay = "RNA",
    cols = c("blue","red")
    ) + 
    RotatedAxis()

6.8 Plot updated tumor proportions per cluster over time

# Tumor samples, week 0, 12, 20 timepoints
as.data.frame(table(merged.18279.tumor.singlets$sub.cluster, merged.18279.tumor.singlets$Sample)) %>% 
  as_tibble() %>%
  dplyr::rename("Sample" = Var2,"Cluster" = Var1) %>%
  separate(Sample, into=c("Patient","Site","Timepoint","IpiCohort","Assay"),sep="_",remove=F) %>%
  dplyr::filter(Timepoint=="W00" | Timepoint=="W12" | Timepoint=="W20") %>%
  group_by(Sample) %>%
  mutate(Proportion = Freq / sum(Freq)) %>%
  ggplot(aes(fill = Timepoint, x = Timepoint, y=Proportion)) +
  geom_point(pch = 21, position = position_jitterdodge(jitter.width=0.2)) +
  facet_wrap(~Cluster,scales="free")

6.9 Save updated object

saveRDS(merged.18279.tumor.singlets, "Tumor_scRNA_Part6.rds")

6.10 Get session info

sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Rocky Linux 8.10 (Green Obsidian)

Matrix products: default
BLAS/LAPACK: /usr/lib64/libopenblasp-r0.3.15.so;  LAPACK version 3.9.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

time zone: America/New_York
tzcode source: system (glibc)

attached base packages:
[1] stats4    stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
 [1] cellXY_0.99.0               scDblFinder_1.14.0         
 [3] harmony_1.2.0               alevinQC_1.16.1            
 [5] vctrs_0.6.5                 patchwork_1.3.0            
 [7] scater_1.30.1               scuttle_1.12.0             
 [9] speckle_1.0.0               Matrix_1.6-4               
[11] fishpond_2.6.2              readxl_1.4.3               
[13] SingleCellExperiment_1.24.0 SummarizedExperiment_1.32.0
[15] Biobase_2.62.0              GenomicRanges_1.54.1       
[17] GenomeInfoDb_1.38.8         IRanges_2.36.0             
[19] S4Vectors_0.40.2            BiocGenerics_0.48.1        
[21] MatrixGenerics_1.14.0       matrixStats_1.4.1          
[23] flexmix_2.3-19              lattice_0.22-6             
[25] SeuratWrappers_0.3.19       miQC_1.8.0                 
[27] lubridate_1.9.3             forcats_1.0.0              
[29] stringr_1.5.1               dplyr_1.1.4                
[31] purrr_1.0.2                 readr_2.1.5                
[33] tidyr_1.3.1                 tibble_3.2.1               
[35] ggplot2_3.5.1               tidyverse_2.0.0            
[37] Seurat_5.1.0                SeuratObject_5.0.2         
[39] sp_2.1-4                    sctransform_0.4.1          
[41] glmGamPoi_1.12.2            presto_1.0.0               
[43] Rcpp_1.0.13-1               devtools_2.4.5             
[45] usethis_3.0.0               data.table_1.16.2          

loaded via a namespace (and not attached):
  [1] fs_1.6.5                  spatstat.sparse_3.1-0    
  [3] bitops_1.0-9              httr_1.4.7               
  [5] RColorBrewer_1.1-3        profvis_0.4.0            
  [7] tools_4.3.2               utf8_1.2.4               
  [9] R6_2.5.1                  DT_0.33                  
 [11] lazyeval_0.2.2            uwot_0.2.2               
 [13] urlchecker_1.0.1          withr_3.0.2              
 [15] GGally_2.2.1              gridExtra_2.3            
 [17] progressr_0.15.1          cli_3.6.3                
 [19] spatstat.explore_3.2-6    fastDummies_1.7.3        
 [21] labeling_0.4.3            spatstat.data_3.1-4      
 [23] ggridges_0.5.6            pbapply_1.7-2            
 [25] Rsamtools_2.18.0          R.utils_2.12.3           
 [27] parallelly_1.39.0         sessioninfo_1.2.2        
 [29] limma_3.58.1              RSQLite_2.3.8            
 [31] BiocIO_1.12.0             generics_0.1.3           
 [33] vroom_1.6.5               gtools_3.9.5             
 [35] ica_1.0-3                 spatstat.random_3.2-2    
 [37] ggbeeswarm_0.7.2          fansi_1.0.6              
 [39] abind_1.4-8               R.methodsS3_1.8.2        
 [41] lifecycle_1.0.4           yaml_2.3.10              
 [43] edgeR_4.0.16              SparseArray_1.2.2        
 [45] Rtsne_0.17                blob_1.2.4               
 [47] grid_4.3.2                dqrng_0.4.1              
 [49] promises_1.3.0            crayon_1.5.3             
 [51] shinydashboard_0.7.2      miniUI_0.1.1.1           
 [53] beachmat_2.18.1           cowplot_1.1.3            
 [55] KEGGREST_1.42.0           metapod_1.10.1           
 [57] pillar_1.9.0              knitr_1.45               
 [59] rjson_0.2.23              xgboost_1.7.8.1          
 [61] future.apply_1.11.3       codetools_0.2-20         
 [63] leiden_0.4.3.1            glue_1.8.0               
 [65] remotes_2.5.0             png_0.1-8                
 [67] spam_2.11-0               org.Mm.eg.db_3.18.0      
 [69] cellranger_1.1.0          gtable_0.3.6             
 [71] cachem_1.1.0              xfun_0.49                
 [73] S4Arrays_1.2.0            mime_0.12                
 [75] survival_3.7-0            bluster_1.12.0           
 [77] statmod_1.5.0             ellipsis_0.3.2           
 [79] fitdistrplus_1.2-1        ROCR_1.0-11              
 [81] nlme_3.1-166              bit64_4.5.2              
 [83] RcppAnnoy_0.0.22          irlba_2.3.5.1            
 [85] vipor_0.4.7               KernSmooth_2.23-24       
 [87] DBI_1.2.3                 colorspace_2.1-1         
 [89] nnet_7.3-19               ggrastr_1.0.2            
 [91] tidyselect_1.2.1          bit_4.5.0                
 [93] compiler_4.3.2            BiocNeighbors_1.20.2     
 [95] DelayedArray_0.28.0       plotly_4.10.4            
 [97] rtracklayer_1.62.0        scales_1.3.0             
 [99] lmtest_0.9-40             digest_0.6.37            
[101] goftest_1.2-3             spatstat.utils_3.1-1     
[103] rmarkdown_2.29            XVector_0.42.0           
[105] htmltools_0.5.8.1         pkgconfig_2.0.3          
[107] sparseMatrixStats_1.14.0  fastmap_1.2.0            
[109] rlang_1.1.4               htmlwidgets_1.6.4        
[111] shiny_1.9.1               DelayedMatrixStats_1.24.0
[113] farver_2.1.2              zoo_1.8-12               
[115] jsonlite_1.8.9            BiocParallel_1.36.0      
[117] R.oo_1.27.0               BiocSingular_1.18.0      
[119] RCurl_1.98-1.16           magrittr_2.0.3           
[121] modeltools_0.2-23         GenomeInfoDbData_1.2.11  
[123] dotCall64_1.2             munsell_0.5.1            
[125] viridis_0.6.5             reticulate_1.35.0        
[127] stringi_1.8.4             zlibbioc_1.48.2          
[129] MASS_7.3-60.0.1           org.Hs.eg.db_3.18.0      
[131] plyr_1.8.9                pkgbuild_1.4.5           
[133] ggstats_0.7.0             parallel_4.3.2           
[135] listenv_0.9.1             ggrepel_0.9.6            
[137] deldir_2.0-4              Biostrings_2.70.3        
[139] splines_4.3.2             tensor_1.5               
[141] hms_1.1.3                 locfit_1.5-9.10          
[143] igraph_2.1.1              spatstat.geom_3.2-8      
[145] RcppHNSW_0.6.0            reshape2_1.4.4           
[147] ScaledMatrix_1.10.0       pkgload_1.4.0            
[149] XML_3.99-0.17             evaluate_1.0.1           
[151] scran_1.30.2              BiocManager_1.30.25      
[153] tzdb_0.4.0                httpuv_1.6.15            
[155] RANN_2.6.2                polyclip_1.10-7          
[157] future_1.34.0             scattermore_1.2          
[159] rsvd_1.0.5                xtable_1.8-4             
[161] restfulr_0.0.15           svMisc_1.2.3             
[163] RSpectra_0.16-2           later_1.3.2              
[165] viridisLite_0.4.2         AnnotationDbi_1.64.1     
[167] GenomicAlignments_1.38.2  memoise_2.0.1            
[169] beeswarm_0.4.0            tximport_1.28.0          
[171] cluster_2.1.6             timechange_0.3.0         
[173] globals_0.16.3